/*
 * Copyright [2013-2021], Alibaba Group Holding Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alibaba.polardbx.common.datatype;

public class DecimalTypeBase {

    public final static int DEFAULT_DIV_PRECISION_INCREMENT = 4;
    public final static String DIV_PRECISION_INCREMENT = "div_precision_increment";


    public static final int DECIMAL_MEMORY_SIZE = 48;
    public static final byte[] BYTES_0 = new byte[DECIMAL_MEMORY_SIZE];


    public static final int E_DEC_OK = 0;
    public static final int E_DEC_TRUNCATED = 1;
    public static final int E_DEC_OVERFLOW = 2;
    public static final int E_DEC_DIV_ZERO = 4;
    public static final int E_DEC_BAD_NUM = 8;
    public static final int E_DEC_OOM = 16;
    public static final int E_DEC_ERROR = 31;
    public static final int E_DEC_FATAL_ERROR = 30;

    public static final int DIV_PRECISION_INCREMENT_DEFAULT = 4;
    public static final int[] BUFF_OFFSETS = {
        0, 4, 8, 12, 16, 20, 24, 28, 32
    };
    public static final byte NEGATIVE_FLAG = 1;
    public static final byte POSITIVE_FLAG = 0;

    public static final int MAX_DECIMAL_PRECISION = 65;
    public static final int MAX_DECIMAL_SCALE = 30;

    protected static final int DIG_BASE = 1000_000_000;
    protected static final int DIG_BASE_2 = DIG_BASE * 2;

    protected static final int DIG_PER_DEC1 = 9;
    protected static final int DIG_MASK = 100000000;
    protected static final int MAX_VALUE_IN_WORDS = DIG_BASE - 1;
    protected static final int WORD_SIZE = 4;

    protected static final int NOT_FIXED_DEC = 31;

    protected static final int WORDS_LEN = 9;
    public static final int INTEGERS_OFFSET = WORDS_LEN * Integer.BYTES;
    public static final int FRACTIONS_OFFSET = INTEGERS_OFFSET + Byte.BYTES;
    public static final int DERIVED_FRACTIONS_OFFSET = FRACTIONS_OFFSET + Byte.BYTES;
    public static final int IS_NEG_OFFSET = DERIVED_FRACTIONS_OFFSET + Byte.BYTES;

    protected final static long LONG_MASK = 0xffffffffL;

    public static final int[] DIV9 = {
        0, 0, 0, 0, 0, 0, 0, 0, 0,
        1, 1, 1, 1, 1, 1, 1, 1, 1,
        2, 2, 2, 2, 2, 2, 2, 2, 2,
        3, 3, 3, 3, 3, 3, 3, 3, 3,
        4, 4, 4, 4, 4, 4, 4, 4, 4,
        5, 5, 5, 5, 5, 5, 5, 5, 5,
        6, 6, 6, 6, 6, 6, 6, 6, 6,
        7, 7, 7, 7, 7, 7, 7, 7, 7,
        8, 8, 8, 8, 8, 8, 8, 8, 8,
        9, 9, 9, 9, 9, 9, 9, 9, 9,
        10, 10, 10, 10, 10, 10, 10, 10, 10,
        11, 11, 11, 11, 11, 11, 11, 11, 11,
        12, 12, 12, 12, 12, 12, 12, 12, 12,
        13, 13, 13, 13, 13, 13, 13, 13, 13,
        14, 14,
    };

    protected static int[] POW_10 = {
        1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};

    protected static int[] DIG_TO_BYTES = {0, 1, 1, 2, 2, 3, 3, 4, 4, 4};

    protected static int roundUp(int digits) {
        int div9Pos = digits + DIG_PER_DEC1 - 1;
        if (div9Pos < DIV9.length) {
            return DIV9[div9Pos];
        }
        return (div9Pos / DIG_PER_DEC1);
    }

    protected static int[][] BINARY_SIZE = {
        {0},
        {1, 1},
        {1, 2, 1},
        {2, 2, 2, 2},
        {2, 3, 2, 3, 2},
        {3, 3, 3, 3, 3, 3},
        {3, 4, 3, 4, 3, 4, 3},
        {4, 4, 4, 4, 4, 4, 4, 4},
        {4, 5, 4, 5, 4, 5, 4, 5, 4},
        {4, 5, 5, 5, 5, 5, 5, 5, 5, 4},
        {5, 5, 5, 6, 5, 6, 5, 6, 5, 5, 5},
        {5, 6, 5, 6, 6, 6, 6, 6, 6, 5, 6, 5},
        {6, 6, 6, 6, 6, 7, 6, 7, 6, 6, 6, 6, 6},
        {6, 7, 6, 7, 6, 7, 7, 7, 7, 6, 7, 6, 7, 6},
        {7, 7, 7, 7, 7, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7},
        {7, 8, 7, 8, 7, 8, 7, 8, 8, 7, 8, 7, 8, 7, 8, 7},
        {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
        {8, 9, 8, 9, 8, 9, 8, 9, 8, 8, 9, 8, 9, 8, 9, 8, 9, 8},
        {8, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9, 8},
        {9, 9, 9, 10, 9, 10, 9, 10, 9, 9, 9, 9, 10, 9, 10, 9, 10, 9, 9, 9},
        {9, 10, 9, 10, 10, 10, 10, 10, 10, 9, 10, 9, 10, 10, 10, 10, 10, 10, 9, 10, 9},
        {10, 10, 10, 10, 10, 11, 10, 11, 10, 10, 10, 10, 10, 10, 11, 10, 11, 10, 10, 10, 10, 10},
        {10, 11, 10, 11, 10, 11, 11, 11, 11, 10, 11, 10, 11, 10, 11, 11, 11, 11, 10, 11, 10, 11, 10},
        {11, 11, 11, 11, 11, 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, 11, 12, 11, 11, 11, 11, 11, 11, 11},
        {11, 12, 11, 12, 11, 12, 11, 12, 12, 11, 12, 11, 12, 11, 12, 11, 12, 12, 11, 12, 11, 12, 11, 12, 11},
        {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12},
        {12, 13, 12, 13, 12, 13, 12, 13, 12, 12, 13, 12, 13, 12, 13, 12, 13, 12, 12, 13, 12, 13, 12, 13, 12, 13, 12},
        {
            12, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 13, 13, 13, 13, 13, 13, 13,
            12},
        {
            13, 13, 13, 14, 13, 14, 13, 14, 13, 13, 13, 13, 14, 13, 14, 13, 14, 13, 13, 13, 13, 14, 13, 14, 13, 14, 13,
            13, 13},
        {
            13, 14, 13, 14, 14, 14, 14, 14, 14, 13, 14, 13, 14, 14, 14, 14, 14, 14, 13, 14, 13, 14, 14, 14, 14, 14, 14,
            13, 14, 13},
        {
            14, 14, 14, 14, 14, 15, 14, 15, 14, 14, 14, 14, 14, 14, 15, 14, 15, 14, 14, 14, 14, 14, 14, 15, 14, 15, 14,
            14, 14, 14, 14},
        {
            14, 15, 14, 15, 14, 15, 15, 15, 15, 14, 15, 14, 15, 14, 15, 15, 15, 15, 14, 15, 14, 15, 14, 15, 15, 15, 15,
            14, 15, 14, 15},
        {
            15, 15, 15, 15, 15, 15, 15, 16, 15, 15, 15, 15, 15, 15, 15, 15, 16, 15, 15, 15, 15, 15, 15, 15, 15, 16, 15,
            15, 15, 15, 15},
        {
            15, 16, 15, 16, 15, 16, 15, 16, 16, 15, 16, 15, 16, 15, 16, 15, 16, 16, 15, 16, 15, 16, 15, 16, 15, 16, 16,
            15, 16, 15, 16},
        {
            16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
            16, 16, 16, 16},
        {
            16, 17, 16, 17, 16, 17, 16, 17, 16, 16, 17, 16, 17, 16, 17, 16, 17, 16, 16, 17, 16, 17, 16, 17, 16, 17, 16,
            16, 17, 16, 17},
        {
            16, 17, 17, 17, 17, 17, 17, 17, 17, 16, 17, 17, 17, 17, 17, 17, 17, 17, 16, 17, 17, 17, 17, 17, 17, 17, 17,
            16, 17, 17, 17},
        {
            17, 17, 17, 18, 17, 18, 17, 18, 17, 17, 17, 17, 18, 17, 18, 17, 18, 17, 17, 17, 17, 18, 17, 18, 17, 18, 17,
            17, 17, 17, 18},
        {
            17, 18, 17, 18, 18, 18, 18, 18, 18, 17, 18, 17, 18, 18, 18, 18, 18, 18, 17, 18, 17, 18, 18, 18, 18, 18, 18,
            17, 18, 17, 18},
        {
            18, 18, 18, 18, 18, 19, 18, 19, 18, 18, 18, 18, 18, 18, 19, 18, 19, 18, 18, 18, 18, 18, 18, 19, 18, 19, 18,
            18, 18, 18, 18},
        {
            18, 19, 18, 19, 18, 19, 19, 19, 19, 18, 19, 18, 19, 18, 19, 19, 19, 19, 18, 19, 18, 19, 18, 19, 19, 19, 19,
            18, 19, 18, 19},
        {
            19, 19, 19, 19, 19, 19, 19, 20, 19, 19, 19, 19, 19, 19, 19, 19, 20, 19, 19, 19, 19, 19, 19, 19, 19, 20, 19,
            19, 19, 19, 19},
        {
            19, 20, 19, 20, 19, 20, 19, 20, 20, 19, 20, 19, 20, 19, 20, 19, 20, 20, 19, 20, 19, 20, 19, 20, 19, 20, 20,
            19, 20, 19, 20},
        {
            20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
            20, 20, 20, 20},
        {
            20, 21, 20, 21, 20, 21, 20, 21, 20, 20, 21, 20, 21, 20, 21, 20, 21, 20, 20, 21, 20, 21, 20, 21, 20, 21, 20,
            20, 21, 20, 21},
        {
            20, 21, 21, 21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21, 21, 21, 21, 21,
            20, 21, 21, 21},
        {
            21, 21, 21, 22, 21, 22, 21, 22, 21, 21, 21, 21, 22, 21, 22, 21, 22, 21, 21, 21, 21, 22, 21, 22, 21, 22, 21,
            21, 21, 21, 22},
        {
            21, 22, 21, 22, 22, 22, 22, 22, 22, 21, 22, 21, 22, 22, 22, 22, 22, 22, 21, 22, 21, 22, 22, 22, 22, 22, 22,
            21, 22, 21, 22},
        {
            22, 22, 22, 22, 22, 23, 22, 23, 22, 22, 22, 22, 22, 22, 23, 22, 23, 22, 22, 22, 22, 22, 22, 23, 22, 23, 22,
            22, 22, 22, 22},
        {
            22, 23, 22, 23, 22, 23, 23, 23, 23, 22, 23, 22, 23, 22, 23, 23, 23, 23, 22, 23, 22, 23, 22, 23, 23, 23, 23,
            22, 23, 22, 23},
        {
            23, 23, 23, 23, 23, 23, 23, 24, 23, 23, 23, 23, 23, 23, 23, 23, 24, 23, 23, 23, 23, 23, 23, 23, 23, 24, 23,
            23, 23, 23, 23},
        {
            23, 24, 23, 24, 23, 24, 23, 24, 24, 23, 24, 23, 24, 23, 24, 23, 24, 24, 23, 24, 23, 24, 23, 24, 23, 24, 24,
            23, 24, 23, 24},
        {
            24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
            24, 24, 24, 24},
        {
            24, 25, 24, 25, 24, 25, 24, 25, 24, 24, 25, 24, 25, 24, 25, 24, 25, 24, 24, 25, 24, 25, 24, 25, 24, 25, 24,
            24, 25, 24, 25},
        {
            24, 25, 25, 25, 25, 25, 25, 25, 25, 24, 25, 25, 25, 25, 25, 25, 25, 25, 24, 25, 25, 25, 25, 25, 25, 25, 25,
            24, 25, 25, 25},
        {
            25, 25, 25, 26, 25, 26, 25, 26, 25, 25, 25, 25, 26, 25, 26, 25, 26, 25, 25, 25, 25, 26, 25, 26, 25, 26, 25,
            25, 25, 25, 26},
        {
            25, 26, 25, 26, 26, 26, 26, 26, 26, 25, 26, 25, 26, 26, 26, 26, 26, 26, 25, 26, 25, 26, 26, 26, 26, 26, 26,
            25, 26, 25, 26},
        {
            26, 26, 26, 26, 26, 27, 26, 27, 26, 26, 26, 26, 26, 26, 27, 26, 27, 26, 26, 26, 26, 26, 26, 27, 26, 27, 26,
            26, 26, 26, 26},
        {
            26, 27, 26, 27, 26, 27, 27, 27, 27, 26, 27, 26, 27, 26, 27, 27, 27, 27, 26, 27, 26, 27, 26, 27, 27, 27, 27,
            26, 27, 26, 27},
        {
            27, 27, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 27, 27, 27, 28, 27,
            27, 27, 27, 27},
        {
            27, 28, 27, 28, 27, 28, 27, 28, 28, 27, 28, 27, 28, 27, 28, 27, 28, 28, 27, 28, 27, 28, 27, 28, 27, 28, 28,
            27, 28, 27, 28},
        {
            28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
            28, 28, 28, 28},
        {
            28, 29, 28, 29, 28, 29, 28, 29, 28, 28, 29, 28, 29, 28, 29, 28, 29, 28, 28, 29, 28, 29, 28, 29, 28, 29, 28,
            28, 29, 28, 29},
        {
            28, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 29, 29, 29, 29, 29, 29, 29,
            28, 29, 29, 29},
        {
            29, 29, 29, 30, 29, 30, 29, 30, 29, 29, 29, 29, 30, 29, 30, 29, 30, 29, 29, 29, 29, 30, 29, 30, 29, 30, 29,
            29, 29, 29, 30},
        {
            29, 30, 29, 30, 30, 30, 30, 30, 30, 29, 30, 29, 30, 30, 30, 30, 30, 30, 29, 30, 29, 30, 30, 30, 30, 30, 30,
            29, 30, 29, 30},
    };
}